/**
 * 
 */
package com.tomagency.cyberlab.test;

import java.math.BigDecimal;
import java.net.URL;
import java.sql.*;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

import com.tomagency.cyberlab.server.config.CyberlabPersistenceManagerImpl;
import com.tomagency.cyberlab.server.imports.PersistenceHelperImpl;
import com.tomagency.cyberlab.server.imports.TaopixConfig;
import com.tomagency.cyberlab.server.imports.TaopixConfigImpl;

import de.gammadata.basics.modelle.BasicRoleDO;
import de.gammadata.basics.modelle.EmailAdresseDO;
import de.gammadata.basics.modelle.HausAdresseDO;
import de.gammadata.basics.modelle.KommAdresseDO;
import de.gammadata.basics.modelle.KontaktDO;
import de.gammadata.basics.modelle.KundenRolleDO;
import de.gammadata.basics.modelle.LandDO;
import de.gammadata.basics.modelle.LieferantenRolleDO;
import de.gammadata.basics.modelle.PersonDO;
import de.gammadata.basics.modelle.UserRolleDO;
import de.gammadata.business.modelle.AbholungDO;
import de.gammadata.business.modelle.BarzahlungDO;
import de.gammadata.business.modelle.GeldDO;
import de.gammadata.business.modelle.KatalogDO;
import de.gammadata.business.modelle.KatalogProduktDO;
import de.gammadata.business.modelle.NettoZahlungsBedingungDO;
import de.gammadata.business.modelle.PaymentServiceZahlungsArtDO;
import de.gammadata.business.modelle.ProduktDO;
import de.gammadata.business.modelle.SteuerDO;
import de.gammadata.business.modelle.VersandArtDO;
import de.gammadata.business.modelle.VersandDO;
import de.gammadata.business.modelle.WrgDO;
import de.gammadata.business.modelle.ZahlungsBedingung;
import de.gammadata.business.modelle.ZahlungsBedingungDO;
import de.gammadata.business.modelle.Produkt.Einheit;
import de.gammadata.gwt.modelle.Wrg;
import de.gammadata.gwt.modelle.Adresse.Nutzung;
import de.gammadata.gwt.modelle.KommAdresse.Type;
import de.gammadata.gwt.modelle.Person.Geschlecht;
import de.gammadata.persistence.KontaktDAO;
import de.gammadata.persistence.LandDAO;
import de.gammadata.persistence.PersistenceManager;
import de.gammadata.persistence.ProduktDAO;
import de.gammadata.persistence.SteuerDAO;
import de.gammadata.persistence.VersandArtDAO;
import de.gammadata.persistence.WrgDAO;
import de.gammadata.persistence.ZahlungsBedingungDAO;
import de.gammadata.persistence.GenericDAO.SEARCHTYPE;
import de.gammadata.util.test.TestPersistenceManagerImpl;

/**
 * Programm füllt wichtige Stammdaten in der Datenbank
 * und führt einige Tests durch.
 * @author gfr
 *
 */
public class FillAndTestDB {

	static Logger logger= null;
	/*
	 *Vielleicht später mit DI erzeugen 
	 */
//	static TaopixLiterale taoLit = new TaopixLiteraleImpl();

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		
		String log4jFile = "META-INF/log4j.properties";
		
		 try {
	    	   ClassLoader cl=Thread.currentThread().getContextClassLoader().getSystemClassLoader();
	    	   
	    	   URL url = cl.getResource(log4jFile);
					PropertyConfigurator.configure(url);
					logger = Logger.getLogger(FillAndTestDB.class);
				}
		 catch (Exception e) {
					System.out.println("Fehler beim konfigurieren log4j, Pfad="+log4jFile);
					e.printStackTrace();
				}
		 
		 EntityManager em=null;
		 PersistenceManager pm=null;
		 TaopixConfig taoLit = new TaopixConfigImpl();
		 PersistenceHelperImpl helper= new PersistenceHelperImpl();
		
		try {
			/*
			 * Ländertabelle von einer vorhandenen SQL-Tabelle füllen
			 */
			logger.info("------------------------ fülle LandDO Tabelle -------------------------");
			LandDAO landDao = new LandDAO();
			Class.forName("com.mysql.jdbc.Driver");
			
			String url =
	            "jdbc:mysql://localhost:3306/iso3166";
			
			Connection con =
                DriverManager.getConnection(
                            url,"tom", "demo");
			
			  logger.info("URL: " + url);
		      logger.info("Connection: " + con);
		      
		      pm = new CyberlabPersistenceManagerImpl();
		      em = pm.getEntityManager();
		      EntityTransaction tx = em.getTransaction();
		      tx.begin();

		      //Get a Statement object
		      Statement stmt;
		      stmt = con.createStatement();
		      
		      ResultSet rs = stmt.executeQuery("SELECT iso, iso3, name, printable_name,numcode FROM country");
		      while (rs.next()) {
		    	  String iso = rs.getString("iso");
		    	  String iso3 = rs.getString("iso3");
		    	  String name = rs.getString("name");
		    	  String printable_name = rs.getString("printable_name");
		    	   int numcode = rs.getInt("numcode");
		    	   LandDO land=null;
		    	   List<LandDO> list=landDao.findByIso2Code(iso, SEARCHTYPE.EXACT, 0, 0, em);
		    	   if (list.size()>0){
		    		   land = list.get(0);
		    		   land.setEigenNamen(printable_name);
			    	   land.setIso3166_2_Code(iso);
			    	   land.setIso3166_3_Code(iso3);
			    	   land.setName(name);
			    	   land.setNummernCode(numcode);
		    		   logger.info("Update Eintrag= id: "+land.getId()+"iso: "+iso+" iso3: "+iso3+" name: "+name+ " printable: "+printable_name+" num: "+numcode);
		    	   }
		    	   else{
			    	   
			    	   land = new LandDO();
			    	   land.setEigenNamen(printable_name);
			    	   land.setIso3166_2_Code(iso);
			    	   land.setIso3166_3_Code(iso3);
			    	   land.setName(name);
			    	   land.setNummernCode(numcode);
			    	   logger.info("Neuer Eintrag= iso: "+iso+" iso3: "+iso3+" name: "+name+ " printable: "+printable_name+" num: "+numcode);
//			    	   em.persist(land);
		    	   }
		    	   if (land!=null)
		    		   landDao.storeEntity(land, em);
		    	   
		    	   

		    		}
		      tx.commit();
		      int max=50;
		      List<LandDO> list=landDao.findAll(0, max, em);
		      
		      if (list!=null){
		    	  logger.info("Liste die ersten "+max+" Länder ----------------");
		    	  for (LandDO land : list){
		    		  logger.info(land.getName()+": "
		    				  +"iso2: "+land.getIso3166_2_Code()
		    				  +", iso3: "+land.getIso3166_3_Code()
		    				  
		    				  + ", printable: "+land.getEigenNamen()
		    				  +", num: "+land.getNummernCode());
		    	  }
		    	  
		    	  logger.info("------------------------ ENDE LandDO Tabelle -------------------------");
		    	  Long anzahl = landDao.countEntities(em);
		    	  logger.info("Anzahl Länder: "+anzahl);
		    	  logger.info("------------------------");
		    	  
		      }
		      else{
		    	  logger.error("Fehler: keine Länder gefundenn --------------");
		      }
		      
		      /*
		       * Währungen füllen
		       */
		      logger.info("------------------------ Währungstabelle erzeugen/prüfen -------------------------");
		       WrgDAO wrgDao = new WrgDAO();
		      
		       WrgDO eur = new WrgDO();
		       eur=helper.wrgEintrag(wrgDao, em, eur);
			   WrgDO dollar = new WrgDO(Wrg.USDOLLAR,Wrg.USDOLLAR_SYMBOL,1.43438);
			   dollar=helper.wrgEintrag(wrgDao, em, dollar);
			   WrgDO pfund = new WrgDO(Wrg.BPD,Wrg.BPD_SYMBOL,0.87489);
			   pfund=helper.wrgEintrag(wrgDao, em, pfund);
			   
			   logger.info("------------------------ Währungstabelle ENDE -------------------------");
			   
			   logger.info("------------------------ Steuertabelle erzeugen/prüfen -------------------------");
			   
			   SteuerDAO steuerDao = new SteuerDAO();
				SteuerDO steuer = new SteuerDO();
				steuer.setBezeichnung("standard");
				steuer.setSteuersatz(new BigDecimal("20"));
				steuer.setValid(true);
				steuer = helper.steuerEintrag(steuerDao, em, steuer);
				
				SteuerDO erm_steuer = new SteuerDO();
				erm_steuer.setBezeichnung("reduziert");
				erm_steuer.setSteuersatz(new BigDecimal("10"));
				erm_steuer.setValid(true);
				erm_steuer = helper.steuerEintrag(steuerDao, em, erm_steuer);
				
				List<SteuerDO> steuern=steuerDao.findBySteuersatz(new BigDecimal("20.00"), SEARCHTYPE.EXACT, 0, 0, em);
				if (steuern!=null&&steuern.size()>0){
					logger.info("Steuersatz 20% gefunden Anzahl: +"+steuern.size()+", Bez: "+steuern.get(0).getBezeichnung()+", Satz: "+steuern.get(0).getSteuersatz());
				}
				else{
					logger.error("Fehler Steuersatz 20% nicht gefunden");
				}
				steuerDao=null;
				logger.info("------------------------ Steuertabelle ENDE -------------------------");
				
				logger.info("------------------------ Produkte erzeugen/prüfen -------------------------");
				
				ProduktDAO pDao = new ProduktDAO();
				KatalogDO taopix_kat = new KatalogDO();
				taopix_kat.setBezeichnung(taoLit.getTaopixKatalogName());
				taopix_kat = (KatalogDO)helper.katalogEintrag(pDao, em, taopix_kat);
				
				ProduktDO fb_15x20 = new ProduktDO(taopix_kat);
				fb_15x20.setArtikelCode("FB_15x20");
				fb_15x20.setBezeichnung("Fotobuch 15x20,5cm quer");
				fb_15x20.setBeschreibung("Fotobuch 15x20,5cm querformat");
				fb_15x20.setSteuer(erm_steuer);
				fb_15x20.setNettoPreis(new GeldDO(new BigDecimal("9.00"),eur));
				fb_15x20.setEinheit(Einheit.STK);				
				fb_15x20 = (ProduktDO)helper.katalogEintrag(pDao, em, fb_15x20);
				taopix_kat.add(fb_15x20);
				
				ProduktDO fb_20x20 = new ProduktDO(taopix_kat);
				fb_20x20.setArtikelCode("FB_20x20");
				fb_20x20.setBezeichnung("Fotobuch 20,5x20,5cm");
				fb_20x20.setBeschreibung("Fotobuch 20,5x20,5cm quardratisch");
				fb_20x20.setSteuer(erm_steuer);
				fb_20x20.setNettoPreis(new GeldDO(new BigDecimal("12.00"),eur));
				fb_20x20.setEinheit(Einheit.STK);				
				fb_20x20 = (ProduktDO)helper.katalogEintrag(pDao, em, fb_20x20);				
				taopix_kat.add(fb_20x20);
				
				ProduktDO fb_20X27_H = new ProduktDO(taopix_kat);
				fb_20X27_H.setArtikelCode("FB_20X27_H");
				fb_20X27_H.setBezeichnung("Fotobuch 20,5x27cm, hoch");
				fb_20X27_H.setBeschreibung("Fotobuch 20,5x27cm, hochformat");
				fb_20X27_H.setSteuer(erm_steuer);
				fb_20X27_H.setNettoPreis(new GeldDO(new BigDecimal("19.00"),eur));
				fb_20X27_H.setEinheit(Einheit.STK);				
				fb_20X27_H = (ProduktDO)helper.katalogEintrag(pDao, em, fb_20X27_H);				
				taopix_kat.add(fb_20X27_H);
				
				ProduktDO fb_20x30Q = new ProduktDO(taopix_kat);
				fb_20x30Q.setArtikelCode("FB_20X30_Q");
				fb_20x30Q.setBezeichnung("Fotobuch A4 (29,7x21cm) quer");
				fb_20x30Q.setBeschreibung("Fotobuch A4 (29,7x21cm) querformat");
				fb_20x30Q.setSteuer(erm_steuer);
				fb_20x30Q.setNettoPreis(new GeldDO(new BigDecimal("24.00"),eur));
				fb_20x30Q.setEinheit(Einheit.STK);				
				fb_20x30Q = (ProduktDO)helper.katalogEintrag(pDao, em, fb_20x30Q);				
				taopix_kat.add(fb_20x30Q);
				
				ProduktDO fb_30x30 = new ProduktDO(taopix_kat);
				fb_30x30.setArtikelCode("FB_30X30");
				fb_30x30.setBezeichnung("Fotobuch 30x29,4cm");
				fb_30x30.setBeschreibung("Fotobuch 30x29,4cm");
				fb_30x30.setSteuer(erm_steuer);
				fb_30x30.setNettoPreis(new GeldDO(new BigDecimal("29.00"),eur));
				fb_30x30.setEinheit(Einheit.STK);				
				fb_30x30 = (ProduktDO)helper.katalogEintrag(pDao, em, fb_30x30);				
				taopix_kat.add(fb_30x30);
				
				EntityTransaction tx2 = em.getTransaction();
				tx2.begin();
				pDao.storeEntity(taopix_kat, em);
				tx2.commit();
				
				List<KatalogProduktDO> produktListe = pDao.findByBezeichnung(taopix_kat.getBezeichnung(), SEARCHTYPE.EXACT, 0, 0, em);
				if (produktListe!=null&&produktListe.size()>0){
					KatalogDO result = (KatalogDO)produktListe.get(0);
					logger.info("Katalog gefunden, Bez: "+result.getBezeichnung()+" ID: "+result.getId()+" Liste Produkte");
					if (result.getKatalogProduktList()!=null && result.getKatalogProduktList().size()>0){												
						for (KatalogProduktDO produkt: result.getKatalogProduktList()){
							if (produkt instanceof ProduktDO){
								ProduktDO p = (ProduktDO)produkt;
								logger.info("Produkt: "+p.getArtikelCode()+", "+p.getBezeichnung()+", brutto: "+p.getBruttoPreis());							
							}
							else{
								logger.info("-------- Katalog : "+produkt.getBezeichnung());
							}
						}
					}
					else{
						logger.error("Fehler: Produktliste ist leer");
					}
				}
				else{
					logger.error("Katalog nicht gefunden: "+taopix_kat.getBezeichnung());
				}
				
				logger.info("------------------------ VERSAND Artikel erzeugen/Prüfen -------------------------");
				
				KatalogDO versand_kat = new KatalogDO();
				versand_kat.setBezeichnung(taoLit.getVersandKatalogName());
				versand_kat = (KatalogDO)helper.katalogEintrag(pDao, em, versand_kat);
				
				ProduktDO versandStdArtikel = taoLit.getVersandArtikel();
				versandStdArtikel.setSteuer(steuer);
				versandStdArtikel.setParent(versand_kat);
				versandStdArtikel.setNettoPreis(new GeldDO(new BigDecimal("0"),eur));
				versandStdArtikel= (ProduktDO)helper.katalogEintrag(pDao, em, versandStdArtikel);
				
				logger.info("Standart Versand-Artikel: "+versandStdArtikel.getArtikelCode()+", "+versandStdArtikel.getBezeichnung()+", Steuersatz: "+versandStdArtikel.getSteuer().getSteuersatz());	
				taoLit.setVersandArtikel(versandStdArtikel);
				
				ProduktDO versandReduziertArtikel = taoLit.getVersandArtikelReduzierteSteuer();
				versandReduziertArtikel.setSteuer(erm_steuer);
				versandReduziertArtikel.setParent(versand_kat);
				versandReduziertArtikel.setNettoPreis(new GeldDO(new BigDecimal("0"),eur));
				versandReduziertArtikel= (ProduktDO)helper.katalogEintrag(pDao, em, versandReduziertArtikel);
				taoLit.setVersandArtikelReduzierteSteuer(versandReduziertArtikel);
				
				logger.info("Reduzierter Versand-Artikel: "+versandReduziertArtikel.getArtikelCode()+", "+versandReduziertArtikel.getBezeichnung()+", Steuersatz: "+versandReduziertArtikel.getSteuer().getSteuersatz());	

				
				logger.info("------------------------ Produkte ENDE -------------------------");
				
				
				logger.info("------------------------ Zahlungsbedingungen erzeugen/prüfen -------------------------");
				ZahlungsBedingungDAO zDao = new ZahlungsBedingungDAO();
				
				BarzahlungDO bar = (BarzahlungDO)taoLit.getBarzahlung();	
				bar = (BarzahlungDO)helper.zahlungsBedingungEintrag(zDao, em, bar);
				taoLit.setBarzahlung(bar);
				
				PaymentServiceZahlungsArtDO paypal = (PaymentServiceZahlungsArtDO)taoLit.getPayPalzahlung();			
				paypal = (PaymentServiceZahlungsArtDO)helper.zahlungsBedingungEintrag(zDao, em, paypal);
				taoLit.setPayPalzahlung(paypal);
				
				NettoZahlungsBedingungDO nettozahlung = (NettoZahlungsBedingungDO)taoLit.getNettozahlung();
				nettozahlung = (NettoZahlungsBedingungDO)helper.zahlungsBedingungEintrag(zDao, em, nettozahlung);
				taoLit.setNettozahlung(nettozahlung);
				
				logger.info("------------------------ Zahlungsbedingungen ENDE -------------------------");
				
				logger.info("------------------------ Versandarten erzeugen/prüfen -------------------------");
				
				VersandArtDAO vDao = new VersandArtDAO();
				
				AbholungDO abholung = (AbholungDO)taoLit.getArtAbholung();
				abholung = (AbholungDO)helper.versandArtEintrag(vDao, em, abholung);
				taoLit.setArtAbholung(abholung);
				
				VersandDO versand = (VersandDO)taoLit.getArtVersand();				
				versand= (VersandDO)helper.versandArtEintrag(vDao, em, versand);
				taoLit.setArtVersand(versand);
				
				VersandDO express = (VersandDO)taoLit.getArtExpressVersand();				
				express= (VersandDO)helper.versandArtEintrag(vDao, em, express);
				taoLit.setArtExpressVersand(express);
				
				logger.info("------------------------ User gfr anlegen -------------------------");
				
				PersonDO gfr = new PersonDO();
				
				
				
				KommAdresseDO mobil = new KommAdresseDO();
				
				gfr.setName("Gammadata GmbH");
				gfr.setVorname("Günther");
				gfr.setNachname("Fröstl");
				gfr.setGeburtsOrt("Stuttgart");
				gfr.setSozialversicherungsNummer("0123456789");
				gfr.setGeschlecht(Geschlecht.MANN);
				
				HausAdresseDO adr = new HausAdresseDO();
				adr.setStadt("Germering");
				adr.setPlz("82110");
				adr.setStrasse("Geschwister-Scholl-Ring 17");
				adr.setLand(landDao.findByIso2Code("DE", em));
				adr.setNutzung(Nutzung.FIRMA);
				gfr.setHauptAdresse(adr);
				
				EmailAdresseDO email = new EmailAdresseDO();
				email.setNameNummer("gfr@gammadata.de");
				email.setNutzung(Nutzung.FIRMA);
				email.setPersonalName("Günther Fröstl Gammadata");
				gfr.setHauptEmailAdresse(email);
				
				KommAdresseDO tel = new KommAdresseDO();
				tel.setNameNummer("+49 89 80095 0");
				tel.setNutzung(Nutzung.FIRMA);
				tel.setType(Type.FESTNETZ);
				gfr.addKommAdresse(tel);
				
				tel = new KommAdresseDO();
				tel.setNameNummer("+49 89 80095 121");
				tel.setNutzung(Nutzung.PRIVAT);
				tel.setType(Type.FESTNETZ);
				gfr.addKommAdresse(tel);
				
				tel = new KommAdresseDO();
				tel.setNameNummer("+49 1515 699 5000");
				tel.setNutzung(Nutzung.FIRMA);
				tel.setType(Type.MOBIL);
				gfr.addKommAdresse(tel);
				
				UserRolleDO user = new UserRolleDO();
				user.setBezugsKontakt(gfr);
				user.setUserName("gfr@gammadata.de");
				user.setPasswort("demo");
				
				if (user.checkPasswort("demo"))
					logger.info("User gfr check passwort ok" );
				else
					logger.error("User gfr check passwort fehlerhaft" );
				
				gfr.addBusinessRolle(user);
				
				KundenRolleDO kunde = new KundenRolleDO();
				kunde.setNummer(999999);
				kunde.setSteuerNummer("117/12345678");
				kunde.setUstId("DE 123456789");				
				gfr.setKundenRolle(kunde);
				
				LieferantenRolleDO lief = new LieferantenRolleDO();
				lief.setNummer(111111);
				lief.setSteuerNummer("117/12345678");
				lief.setUstId("DE 123456789");				
				gfr.addBusinessRolle(lief);
				
				KontaktDAO kDao = new KontaktDAO();
				int gfrId = 0;
				EntityTransaction txgfr = em.getTransaction();
				try {
					txgfr.begin();
					gfr = (PersonDO)kDao.storeEntity(gfr, em);					
					txgfr.commit();
					gfrId= gfr.getId();
					logger.info("KontaktDO gfr abgespeichert ID: "+gfrId);
				} 
				catch (Exception e) {
					tx.rollback();
					logger.error("Fehler beim Abspeichern KontaktDO gfr",e);
				}
				
					
				
				
				
				em.close();
				logger.info("------------------------ User gfr anlegen/prüfen -------------------------");
				em = pm.getEntityManager();
				
				KontaktDO gfrp = kDao.findById(gfrId, em);
				if (gfrp!=null){
					logger.info("Kontakt gefunden ID: "+gfrId);
					logger.info("Name: \n"+gfr.getNamenString());
					logger.info("Adr: \n"+gfr.getAdressString());
					logger.info("Email: "+gfr.getHauptEmailAdresse().getMatchString());
					for (KommAdresseDO kom : gfr.getKommAdressenListe()){
						logger.info("Komm "+kom.getType()+": "+kom.getMatchString());						
					}
					
					logger.info("Kunde: "+gfr.getKundenRolle().getRollenString());
					for (BasicRoleDO rolle: gfr.getBusinessRollenList()){
						logger.info("Rolle: "+rolle.getClassName()+" "+rolle.getRollenString());
					}
				}
				else{
					logger.error("Kontakt nicht gefunden ID: "+gfrId);
				}

		      /*
		       * E N D E
		       */
		     
		      
		} catch (Exception e) {
			 logger.error("Fehler. "+e.getMessage(),e);
		}
		finally{
			if(em!=null){
				em.clear();
				em.close();
			}
			if(pm!=null){
				pm.getCurrentEntityManagerFactory().close();
			}
		}
		logger.info("------------------------ "+FillAndTestDB.class.getSimpleName()+" ENDE -------------------------");

	}

}
